<template>
    <div class="tr-edit-box" :id="trEditId">
      <slot></slot>
      <el-dialog :visible.sync="dialogShow" :close-on-click-modal="false" :close-on-press-escape="false"
        :show-close="false" :modal-append-to-body="true" :append-to-body="true" :custom-class="`tr-edit ${trEditId}`">
        <div class="h-100p" @keydown="event => { if (event.keyCode === 13) return false; }">
          <slot name="trEditForm"></slot>
        </div>
        <div slot="footer" class="dialog-footer">
          <el-button size="small" v-if="!confirmButtonDisabled" type="primary" @click="handleConfirm">确 定</el-button>
          <el-button size="small" v-else type="primary">确 定</el-button>
          <el-button size="small" @click="handleCancel">取 消</el-button>
        </div>
      </el-dialog>
    </div>
  </template>
  <script>
  export default {
    name: 'ui-tr-edit',
    props: {
      rowData: {},
      validate: {
        type: Boolean,
        default: false
      },
      tableData: {},
      editedList: Array,
      trEditId: {
        type: String,
        default: 'tr-edit'
      },
      trEditFormRef: {
        type: String,
        default: 'trEditForm'
      }
    },
    data() {
      return {
        dialogShow: false,
        oldData: {},
        rowNum: '',
        confirmButtonDisabled: false,
        initTableData: JSON.parse(JSON.stringify(this.tableData))
      }
    },
    computed: {
      outEditHandle() {
        return this.$store.state['trEdit'].editFlag
      }
    },
    mounted() {
      window.addEventListener('resize', this.handleResize)
      window.addEventListener('keyup', this.escCancel)
  
      //特殊处理
      //处理时间组件弹出层z-index
      jQuery('#' + this.trEditId + '.tr-edit-box').on('click', '.el-date-editor', function () {
        let dialogZindex = Number(jQuery('.el-dialog.tr-edit .el-dialog__wrapper').css('z-index'))
        let datePanel = jQuery(this).hasClass('el-date-editor--time')
          ? jQuery('.el-time-panel')
          : jQuery('.el-date-picker')
        if (Number(datePanel.css('z-index')) <= dialogZindex) {
          datePanel.css('z-index', dialogZindex + 1)
        }
      })
    },
    beforeDestroy() {
      window.removeEventListener('resize', this.handleResize)
      window.removeEventListener('keyup', this.escCancel)
    },
    watch: {
      rowData: {
        handler: function (val, oldVal) {
          setTimeout(() => {
            this.onEdit()
            if (this.findTrEditForm(this)) {
              this.findTrEditForm(this).validate(valid => {
                this.confirmButtonDisabled = !valid
              })
            } else {
              this.$nextTick(() => {
                let formRef = this.onGetFormRef()
                formRef.componentInstance.validate(valid => {
                  this.confirmButtonDisabled = !valid
                })
              })
            }
          })
        },
        deep: true
      },
      outEditHandle: {
        handler: function (val, oldVal) {
          this.onEdit(val)
        },
        deep: true
      }
    },
    methods: {
      onEdit(val) {
        let editFlag = val || this.$store.state['trEdit'].editFlag
        if (editFlag.trEditId === this.trEditId) {
          let _this = this
          _this.rowNum = editFlag.index
          _this.dialogShow = true
          _this.oldData = JSON.parse(JSON.stringify(_this.rowData)) //保存初始值
          _this.updatePosition()
        }
      },
      escCancel(e) {
        // ESC键取消整行编辑
        if (e.key === 'Escape' && this.dialogShow) this.handleCancel()
      },
      handleConfirm() {
        if (this.validate) {
          this.findTrEditForm(this).validate(valid => {
            if (valid) {
              this.ensure()
            } else {
              return false
            }
          })
        } else {
          this.ensure()
        }
        this.$emit('confirm')
      },
      handleCancel() {
        if (this.validate) {
          this.findTrEditForm(this).resetFields()
        }
        for (let key in this.rowData) {
          this.$set(this.rowData, key, this.oldData[key])
        }
        this.dialogShow = false
        this.$emit('cancel')
      },
      onGetFormRef() {
        let res = null
        if (this.$slots['trEditForm'] && this.$slots['trEditForm'][0]) {
          res = this.$slots['trEditForm'][0]
        }
        return res
      },
      _findForm(_this) {
        if (_this.$parent) {
          if (_this.$parent.$refs[this.trEditFormRef]) {
            return _this.$parent.$refs[this.trEditFormRef]
          }
          _this = _this.$parent
          return this.findTrEditForm(_this)
        }
        return false
      },
      findTrEditForm(_this) {
        let flag = false
        if (this._findForm(_this)) {
          flag = this._findForm(_this)
        } else {
          flag = this.onGetFormRef()
        }
        return flag
      },
      updatePosition() {
        this.$nextTick(() => {
          //设定外围
          let boxWidth = jQuery('#' + this.trEditId + '.tr-edit-box').width()
          let boxLeft = jQuery('#' + this.trEditId + '.tr-edit-box').offset().left
          const tableRow = jQuery('#' + this.trEditId + '.tr-edit-box .el-table > .el-table__body-wrapper tr.el-table__row')
          let row = tableRow.length ? tableRow.eq(this.rowNum) : jQuery('#' + this.trEditId + '.tr-edit-box .el-table > .el-table__body-wrapper table tbody')
          let boxTop = row.length ? row.offset().top : (tableRow.eq(this.rowNum - 1).offset().top) + 47
          let boxHeight = row.height() || 47
          jQuery('.el-dialog.tr-edit').css({
            width: boxWidth,
            height: boxHeight,
            left: boxLeft,
            top: boxTop
          })
          //设定内容
          let cols = row.find('td:not(.tr-edit-operate)')
          let formItems = jQuery(`.el-dialog.tr-edit.${this.trEditId} .el-dialog__body .el-form > .el-form-item`)
          for (let i = 0; i < cols.length; i++) {
            let colWidth = cols[i].clientWidth
            jQuery(formItems[i]).width(colWidth)
          }
          //设定按钮
          let dialogFooter = jQuery('.el-dialog.tr-edit .el-dialog__footer')
          dialogFooter.removeClass('dialog-top-footer').css('margin-top', 0)
          let footerTop = dialogFooter.offset().top
          let footerHeight = dialogFooter.height()
          let documentHeight = document.documentElement.clientHeight
          if (footerTop + footerHeight > documentHeight) {
            dialogFooter.addClass('dialog-top-footer').css('margin-top', -(boxHeight + footerHeight))
          }
        })
      },
      handleResize() {
        if (this.dialogShow) this.handleCancel()
      },
      checkEdit() {
        for (let key in this.initTableData) {
          if (this.initTableData[key].id === this.rowData.id) {
            for (let i in this.rowData) {
              if (this.initTableData[key][i] !== this.rowData[i]) {
                return true
              }
            }
          }
        }
        return false
      },
      isInEditedList() {
        for (let key in this.editedList) {
          if (this.editedList[key].id === this.rowData.id) {
            return key
          }
        }
        return false
      },
      ensure() {
        let row = jQuery(
          jQuery('#' + this.trEditId + '.tr-edit-box .el-table table tbody tr.el-table__row')[this.rowNum]
        )
        if (this.checkEdit()) {
          //修改
          row.addClass('edited-tr')
          if (this.isInEditedList() === false) {
            this.editedList.push(this.rowData)
          }
        } else {
          //未修改
          row.removeClass('edited-tr')
          if (this.isInEditedList() !== false) {
            this.editedList.splice(this.isInEditedList(), 1)
          }
        }
        this.dialogShow = false
      }
    }
  }
  </script>
  <style scoped lang="scss">
  .tr-edit-box {
    position: relative;
  }
  
  .el-dialog__wrapper {
    & /deep/ .tr-edit {
      margin: 0 !important;
      transform: translateX(0);
  
      .el-dialog__header {
        height: 0;
        padding: 0;
      }
  
      .el-dialog__body {
        height: 100%;
        padding: 0;
      }
  
      .el-dialog__footer {
        padding: 0 20px 0;
        text-align: center;
  
        .dialog-footer {
          display: inline-block;
          padding: 10px 10px 10px;
          background: #fff;
          border-radius: 0 0 2px 2px;
          box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3);
        }
      }
  
      .dialog-top-footer {
        .dialog-footer {
          border-radius: 2px 2px 0 0;
          box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.3);
        }
      }
  
      .el-form {
        height: 100%;
        display: flex;
  
        .el-form-item {
          display: inline-block;
          margin: auto 0;
  
          .el-form-item__content {
            padding: 0 6px;
            line-height: 47px;
          }
        }
      }
    }
  }
  
  /*.dialog-fade-enter-active{
            animation:cover;
        }
        .dialog-fade-leave-active{
            animation:cover;
        }*/
  
  /*.el-picker-panel {
                z-index: 9999999999 !important;
            }*/
  </style>